package com.errol.batchprocessor.batchprocessor.payload;

import lombok.Getter;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * 批处理模型 一个导入批次唯一的计数器
 *
 * @author zhang xiao bin
 * @version v1.0
 * @date 2021/02/23
 * @since v5.0.5
 **/
@Getter
public final class BatchCounter {

    /**
     * 已开始的分片数：被线程池运行就算开始
     */
    private final AtomicInteger startedPieces;
    /**
     * 未完成的分片数：未开始、处理中的分片数；不包括已完成、已中断的分片
     */
    private final AtomicInteger undonePieces;
    /**
     * 批次启动状态：null-未启动完成（默认）、true-启动成功、false-启动失败
     */
    private volatile Boolean batchStarted;
    /**
     * 是否存在执行失败的分片：false-无失败分片（默认）、true-存在失败分片
     */
    private volatile Boolean piecesFailed;
    /**
     * 最后一个抛出的分片异常提示：时间 + 异常描述
     */
    private volatile String lastPieceErrorMessageHint;

    public BatchCounter(int piecesAmount) {
        this.startedPieces = new AtomicInteger(0);
        this.undonePieces = new AtomicInteger((piecesAmount));
        this.batchStarted = null;
        this.piecesFailed = false;
    }

    public boolean startOneMissionPiece() {
        return startedPieces.addAndGet(1) == 1;
    }

    public boolean finishOneMissionPiece() {
        return undonePieces.addAndGet(-1) == 0;
    }

    public boolean interruptOneMissionPiece() {
        if (!piecesFailed) {
            piecesFailed = true;
        }
        return finishOneMissionPiece();
    }

    public void startBatchSuccess() {
        batchStarted = true;
    }

    public void startBatchFailed() {
        batchStarted = false;
    }

    public boolean isBatchStarting() {
        return batchStarted == null;
    }

    public boolean isBatchStartSuccess() {
        return Boolean.TRUE.equals(batchStarted);
    }

    public boolean isAllPiecesSuccess() {
        return !piecesFailed;
    }

    public void setLastPieceErrorMessageHint(String lastPieceErrorMessageHint) {
        this.lastPieceErrorMessageHint = lastPieceErrorMessageHint;
    }
}
